﻿Public Class SecurityManager
    <Flags>
    Public Enum Permission
        None = 0
        View = 1
        Execute = 2
        Create = 4
        Modify = 8
        Delete = 16
    End Enum

    Private Class ObjectType
        Shared ReadOnly Property Job As String
            Get
                Return "Job"
            End Get
        End Property
        Shared ReadOnly Property Script As String
            Get
                Return "Script"
            End Get
        End Property
        Shared ReadOnly Property User As String
            Get
                Return "User"
            End Get
        End Property
        Shared ReadOnly Property Role As String
            Get
                Return "Role"
            End Get
        End Property
        Shared ReadOnly Property Category As String
            Get
                Return "Category"
            End Get
        End Property
    End Class

    Private Shared Function Validate(user As System.Security.Principal.WindowsPrincipal, objectType As String, objectId As Integer, permissionType As Permission) As Boolean
        Using db As New PowerShellCronContext
            Return Validate(db, user, objectType, objectId, permissionType)
        End Using
    End Function

    Private Shared Function Validate(db As PowerShellCronContext, user As System.Security.Principal.WindowsPrincipal, objectType As String, objectId As Integer, permissionType As Permission) As Boolean
        Dim cu As System.Security.Principal.WindowsPrincipal = System.Security.Principal.WindowsPrincipal.Current
        Dim userName As String = cu.Identity.Name

        Dim q = db.SecurityUser.Where(Function(x) x.Roles.Any(Function(y) y.Access.Any(Function(z) (z.ObjectType Is Nothing Or z.ObjectType = objectType) And (z.ObjectID Is Nothing Or z.ObjectID = objectId) And ((z.Permissions And permissionType) = permissionType))))
        If q.Any(Function(x) x.IsGroup = False And x.Name = userName) Then
            Return True
        Else
            For Each su As SecurityUser In q.Where(Function(x) x.IsGroup = True)
                If cu.IsInRole(su.Name) Then Return True
            Next
        End If
        Return False
    End Function

    Friend Shared Function CheckJob(user As System.Security.Principal.WindowsPrincipal, jobId As Integer, categoryId As Integer, permissionType As Permission, db As PowerShellCronContext) As Boolean
        Return Validate(db, user, ObjectType.Category, categoryId, permissionType) OrElse Validate(db, user, ObjectType.Job, jobId, permissionType)
    End Function

    Friend Shared Function CheckScript(user As System.Security.Principal.WindowsPrincipal, scriptId As Integer, categoryId As Integer, permissionType As Permission, db As PowerShellCronContext) As Boolean
        Return Validate(db, user, ObjectType.Category, categoryId, permissionType) OrElse Validate(db, user, ObjectType.Script, scriptId, permissionType)
    End Function

    Friend Shared Function CheckUser(user As System.Security.Principal.WindowsPrincipal, userId As Integer, permissionType As Permission, db As PowerShellCronContext) As String
        Return Validate(db, user, ObjectType.User, userId, permissionType)
    End Function

    Friend Shared Function CheckRole(user As System.Security.Principal.WindowsPrincipal, roleId As Integer, permissionType As Permission, db As PowerShellCronContext) As String
        Return Validate(db, user, ObjectType.Role, roleId, permissionType)
    End Function

    Friend Shared Function CheckCategory(user As System.Security.Principal.WindowsPrincipal, categoryId As Integer, permissionType As Permission, db As PowerShellCronContext) As String
        Return Validate(db, user, ObjectType.Category, categoryId, permissionType)
    End Function
End Class

